package com.henry.utils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author henryGui
 * @version V1.0
 * @Title: GeneratorProject
 * @Package com.henry.utils
 * @Description: TODO
 * @date 2019-02-19 5:22 PM
 */
@Component
public class GeneratorProject {
    private VelocityContext context;
    private VelocityEngine ve = new VelocityEngine();
    private final String TEMPLATE_PATH = "src/main/resources/template_project";




    //创建项目名称
    private String project_artifactId="personal-cloud-provider-anbang";
    private String project_groupId="com.doubao.personal.anbang";
    private String project_version="4.0.0";
    //存放项目路径
    //src下包名
    private String project_packageName="com.doubao.personal.anbang";
    private String root_dir="/Users/wuzhenggui/work/IdeaProjects/mayun/personal-cloud";
    private String appName="IssuingAnBangApplication";

    private String spring_cloud_config_name="personal-cloud-provider-api";


    private String src_java_dir;
    private String src_resources_dir;
    private String package_dir;
    private String src_test_dir;

    @PostConstruct
    private void initData() {
        //设置velocity资源加载器
        Properties prop = new Properties();
        prop.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, TEMPLATE_PATH); //此处的fileDir可以直接用绝对路径来
        ve.init(prop);

        _createSrcStructure();

    }







    private void _createSrcStructure(){
        root_dir=root_dir.replace("//","/");
        src_java_dir=root_dir+"/"+this.project_artifactId+ "/src/main/java/";
        src_resources_dir=root_dir+"/"+this.project_artifactId+ "/src/main/resources/";

        package_dir=src_java_dir+"/"+project_packageName.replace(".","/")+"/";
        src_test_dir=root_dir+"/"+this.project_artifactId+ "/src/test/";

        createDirs(src_java_dir);
        createDirs(src_resources_dir);
        createDirs(package_dir);
        createDirs(src_test_dir);

        createDirs(package_dir+"/config");
        createDirs(package_dir+"/controller");
        createDirs(package_dir+"/dao/mapper");
        createDirs(package_dir+"/dao/entity");
        createDirs(package_dir+"/service");
        createDirs(package_dir+"/utils");

    }


    public void createPomXml() throws IOException {
        Template t = ve.getTemplate("pom.vm","UTF-8");
        VelocityContext ctx = new VelocityContext();

        ctx.put("version", this.project_version);
        ctx.put("artifactId", this.project_artifactId);
        ctx.put("groupId", this.project_groupId);

        StringWriter sw = new StringWriter();
        t.merge(ctx, sw);
//        System.out.println(sw.toString());
        this.createFile(sw.toString(),this.root_dir+"/"+this.project_artifactId+"/pom.xml");
    }

    public void createProperties() throws IOException {
        Template t = ve.getTemplate("application_properties.vm","UTF-8");
        VelocityContext ctx = new VelocityContext();

        ctx.put("version", this.project_version);
        ctx.put("artifactId", this.project_artifactId);
        ctx.put("groupId", this.project_groupId);

        ctx.put("spring_cloud_config_name", this.spring_cloud_config_name);

        StringWriter sw = new StringWriter();
        t.merge(ctx, sw);
//        System.out.println(sw.toString());
        this.createFile(sw.toString(),this.src_resources_dir+"/application.properties");
        t = ve.getTemplate("bootstrap.vm","UTF-8");
        sw = new StringWriter();
        t.merge(ctx, sw);
//        System.out.println(sw.toString());
        this.createFile(sw.toString(),this.src_resources_dir+"/bootstrap.properties");
    }

    public void createApplicationJava() throws IOException {
        Template t = ve.getTemplate("application_java.vm","UTF-8");
        VelocityContext ctx = new VelocityContext();

        ctx.put("packageName", this.project_packageName);

        if(StringUtils.isBlank(appName)){
            appName=this.lineToHump(project_artifactId,true)+"Application";
        }
        System.out.println(appName);
        ctx.put("appName", appName);
        ctx.put("appNameClass", appName+".class");


        StringWriter sw = new StringWriter();
        t.merge(ctx, sw);
//       System.out.println(sw.toString());
        this.createFile(sw.toString(),this.package_dir+appName+".java");

    }

    public void createDataSource() throws IOException {


        Template t = ve.getTemplate("DataSourceConfig_java.vm","UTF-8");
        VelocityContext ctx = new VelocityContext();

        ctx.put("packageName", this.project_packageName);
        ctx.put("packageName_", this.project_packageName.replace(".","/"));


        String dataSourceConfigName="DataSourceConfig";
        ctx.put("dataSourceConfigName", dataSourceConfigName);


        StringWriter sw = new StringWriter();
        t.merge(ctx, sw);
//       System.out.println(sw.toString());
        this.createFile(sw.toString(),this.package_dir+"config/"+dataSourceConfigName+".java");
    }



    private void createFile(String content,String fileFullPath) throws IOException {
        IOUtils.write(content, new FileOutputStream(new File(fileFullPath)), "UTF-8");

    }



    private void createDirs(String dirs) {
        File fp = new File(dirs);
        // 创建目录
        if (fp.exists()) {
//           fp.delete();
            try {
                FileUtils.deleteDirectory(fp);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        fp.mkdirs();// 目录不存在的情况下，创建目录。
        System.out.println("执行结束"+dirs);

    }



    private static Pattern linePattern = Pattern.compile("(_|-)(\\w)");
    /**下划线转驼峰*/
    public static String lineToHump(String str,boolean firstUp){
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()){
            matcher.appendReplacement(sb, matcher.group(0).toUpperCase());
        }
        matcher.appendTail(sb);
        String result=sb.toString();
        if(firstUp){
            result = result.replace(result.substring(0,1),result.substring(0,1).toUpperCase());
        }
        return result.replace("_","").replace("-","");
    }

    private static Pattern humpPattern = Pattern.compile("[A-Z]");
    /**驼峰转下划线,效率比上面高*/
    public static String humpToLine2(String str){
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()){
            matcher.appendReplacement(sb, "_"+matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }



    public void ss(){
        Template t = ve.getTemplate("hellovelocity.vm");
        VelocityContext ctx = new VelocityContext();

        ctx.put("name", "velocity");
        ctx.put("date", (new Date()).toString());

        List temp = new ArrayList();
        temp.add("1");
        temp.add("2");
        ctx.put( "list", temp);

        StringWriter sw = new StringWriter();
        t.merge(ctx, sw);
        System.out.println(sw.toString());
    }
}
